From e4096c828807f6c3567ce43db2d79a924e397124 Mon Sep 17 00:00:00 2001 From: Richard Lowe Date: Tue, 6 Aug 2013 21:29:05 -0400 Subject: [PATCH] 4003 dldump() can't deal with extended sections Reviewed by: Jason King Reviewed by: Josef 'Jeff' Sipek Approved by: Robert Mustacchi --- usr/src/cmd/sgs/librtld/common/dldump.c | 55 +++++++++++++++++++++---- usr/src/cmd/sgs/librtld/common/librtld.msg | 4 +- usr/src/cmd/sgs/packages/common/SUNWonld-README | 1 + 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/usr/src/cmd/sgs/librtld/common/dldump.c b/usr/src/cmd/sgs/librtld/common/dldump.c index 6ac021e5e7..5149d12267 100644 --- a/usr/src/cmd/sgs/librtld/common/dldump.c +++ b/usr/src/cmd/sgs/librtld/common/dldump.c @@ -25,7 +25,6 @@ * * dldump(3c) creates a new file image from the specified input file. */ -#pragma ident "%Z%%M% %I% %E% SMI" #include #include @@ -158,7 +157,7 @@ rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr) Elf_Data *data; Half endx = 1; int fd = 0, err, num; - size_t shstr_size = 1; + size_t shstr_size = 1, shndx; Addr edata; char *shstr, *_shstr, *ipath = NAME(lmp); prstatus_t *status = 0, _status; @@ -309,7 +308,13 @@ rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr) /* * Obtain the input files section header string table. */ - if ((scn = elf_getscn(ielf, iehdr->e_shstrndx)) == NULL) { + + if (elf_getshdrstrndx(ielf, &shndx) == -1) { + eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRSTRNDX), ipath); + cleanup(ielf, oelf, melf, icache, mcache, fd, opath); + return (1); + } + if ((scn = elf_getscn(ielf, shndx)) == NULL) { eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSCN), ipath); cleanup(ielf, oelf, melf, icache, mcache, fd, opath); return (1); @@ -327,10 +332,18 @@ rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr) * add an additional entry (marked FLG_C_END) to make the processing of * this cache easier. */ - num = iehdr->e_shnum; + + if (elf_getshdrnum(ielf, &shndx) == -1) { + eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRNUM), opath); + cleanup(ielf, oelf, melf, icache, mcache, fd, opath); + return (1); + } + + num = shndx; + if (status) num++; - if ((icache = malloc((num + 1) * sizeof (Cache))) == 0) { + if ((icache = calloc(num + 1, sizeof (Cache))) == 0) { cleanup(ielf, oelf, melf, icache, mcache, fd, opath); return (1); } @@ -420,7 +433,7 @@ rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr) if (status) { _icache++; _icache->c_name = - (char *)MSG_ORIG(MSG_SCN_HEAP); + (char *)MSG_ORIG(MSG_SCN_HEAP); _icache->c_flags = FLG_C_HEAP; _icache->c_scn = 0; @@ -624,7 +637,27 @@ rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr) _icache->c_info = shstr; /* LINTED */ - oehdr->e_shstrndx = (Half)elf_ndxscn(scn); + if (elf_ndxscn(scn) >= SHN_LORESERVE) { + Elf_Scn *_scn; + Shdr *shdr0; + + /* + * libelf deals with e_shnum for us, but we + * need to deal with e_shstrndx ourselves. + */ + oehdr->e_shstrndx = SHN_XINDEX; + if ((_scn = elf_getscn(oelf, 0)) == NULL) { + eprintf(lml, ERR_ELF, + MSG_ORIG(MSG_ELF_GETSCN), opath); + cleanup(ielf, oelf, melf, icache, + mcache, fd, opath); + return (1); + } + shdr0 = elf_getshdr(_scn); + shdr0->sh_link = elf_ndxscn(scn); + } else { + oehdr->e_shstrndx = (Half)elf_ndxscn(scn); + } } else if (_icache->c_flags == FLG_C_HEAP) { /* @@ -727,10 +760,16 @@ rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr) return (1); } + if (elf_getshdrnum(melf, &shndx) == -1) { + eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRNUM), opath); + cleanup(ielf, oelf, melf, icache, mcache, fd, opath); + return (1); + } + /* * Construct a cache to maintain the memory files section information. */ - if ((mcache = malloc(mehdr->e_shnum * sizeof (Cache))) == 0) { + if ((mcache = calloc(shndx, sizeof (Cache))) == 0) { cleanup(ielf, oelf, melf, icache, mcache, fd, opath); return (1); } diff --git a/usr/src/cmd/sgs/librtld/common/librtld.msg b/usr/src/cmd/sgs/librtld/common/librtld.msg index 5b8a52886c..ecb4ab1e3b 100644 --- a/usr/src/cmd/sgs/librtld/common/librtld.msg +++ b/usr/src/cmd/sgs/librtld/common/librtld.msg @@ -22,8 +22,6 @@ # # CDDL HEADER END # -# ident "%Z%%M% %I% %E% SMI" - @ _START_ @@ -70,6 +68,8 @@ @ MSG_ELF_GETPHDR "%s: elf_getphdr" @ MSG_ELF_GETSCN "%s: elf_getscn" @ MSG_ELF_GETSHDR "%s: elf_getshdr" +@ MSG_ELF_GETSHDRNUM "%s: elf_getshdrnum" +@ MSG_ELF_GETSHDRSTRNDX "%s: elf_getshdrstrndx" @ MSG_ELF_NEWDATA "%s: elf_newdata" @ MSG_ELF_NEWEHDR "%s: elf_newehdr" @ MSG_ELF_NEWPHDR "%s: elf_newphdr" diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index bd4314d9e3..71cb2a1743 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1649,3 +1649,4 @@ Bugid Risk Synopsis 3722 link-editor is over restrictive of R_AMD64_32 addends 3926 multiple extern map file definitions corrupt symbol table entry 3999 libld extended section handling is broken +4003 dldump() can't deal with extended sections -- 2.11.4.GIT