Print this page
4003 dldump() can't deal with extended sections
@@ -23,11 +23,10 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* dldump(3c) creates a new file image from the specified input file.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/param.h>
#include <sys/procfs.h>
#include <fcntl.h>
#include <stdio.h>
@@ -156,11 +155,11 @@
Elf_Scn *scn;
Shdr *shdr;
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;
Lm_list *lml = LIST(lmp);
Alist *nodirect = 0;
@@ -307,11 +306,17 @@
}
/*
* 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);
}
if ((data = elf_getdata(scn, NULL)) == NULL) {
@@ -325,11 +330,19 @@
* Construct a cache to maintain the input files section information.
* Obtain an extra cache element if a heap addition is required. Also
* 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) {
cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
return (1);
@@ -622,11 +635,31 @@
data->d_size = shstr_size;
_icache->c_info = shstr;
/* LINTED */
+ 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) {
/*
* Assign the heap to the appropriate memory offset.
*/
@@ -725,14 +758,20 @@
eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETEHDR), opath);
cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
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 = malloc(shndx * sizeof (Cache))) == 0) {
cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
return (1);
}
_mcache = mcache;
_mcache++;