Skip to content

Commit f71b5e7

Browse files
committed
merge D2 pull #1540
1 parent 4f2ccf8 commit f71b5e7

File tree

4 files changed

+126
-62
lines changed

4 files changed

+126
-62
lines changed

src/backend/cdef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ typedef targ_uns targ_size_t; /* size_t for the target machine */
572572
#define DATA 2 /* initialized data */
573573
#define CDATA 3 /* constant data */
574574
#define UDATA 4 /* uninitialized data */
575-
#define UNKNOWN 0x7FFF // unknown segment
575+
#define UNKNOWN -1 /* unknown segment */
576576
#define DGROUPIDX 1 /* group index of DGROUP */
577577

578578
#define KEEPBITFIELDS 0 /* 0 means code generator cannot handle bit fields, */

src/backend/elfobj.c

Lines changed: 112 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,17 @@ Outbuffer *SECbuf; // Buffer to build section table in
216216
// not used.
217217
static int section_cnt; // Number of sections in table
218218

219-
#define SHI_TEXT 1
220-
#define SHI_RELTEXT 2
221-
#define SHI_DATA 3
222-
#define SHI_RELDATA 4
223-
#define SHI_BSS 5
224-
#define SHI_RODAT 6
225-
#define SHI_STRINGS 7
226-
#define SHI_SYMTAB 8
227-
#define SHI_SECNAMES 9
228-
#define SHI_COM 10
229-
#define SHI_NOTE 11
219+
#define SHN_TEXT 1
220+
#define SHN_RELTEXT 2
221+
#define SHN_DATA 3
222+
#define SHN_RELDATA 4
223+
#define SHN_BSS 5
224+
#define SHN_RODAT 6
225+
#define SHN_STRINGS 7
226+
#define SHN_SYMTAB 8
227+
#define SHN_SECNAMES 9
228+
#define SHN_COM 10
229+
#define SHN_NOTE 11
230230

231231
IDXSYM *mapsec2sym;
232232
#define S2S_INC 20
@@ -252,6 +252,10 @@ static int local_cnt; // Number of symbols with STB_LOCAL
252252
// Symbol Table
253253
Outbuffer *SYMbuf; // Buffer to build symbol table in
254254

255+
// Extended section header indices
256+
static Outbuffer *shndx_data;
257+
static const IDXSEC secidx_shndx = SHN_HIRESERVE + 1;
258+
255259
// Notes data (note currently used)
256260
static Outbuffer *note_data;
257261
static IDXSEC secidx_note; // Final table index for note data
@@ -458,9 +462,22 @@ static IDXSYM elf_addsym(IDXSTR nam, targ_size_t val, unsigned sz,
458462
*/
459463
if(sz == 0 && (bind == STB_GLOBAL || bind == STB_WEAK) &&
460464
(typ == STT_OBJECT || typ == STT_TLS) &&
461-
sec != SHT_UNDEF)
465+
sec != SHN_UNDEF)
462466
sz = 1; // so fake it if it doesn't
463467

468+
if (sec > SHN_HIRESERVE)
469+
{ // If the section index is too big we need to store it as
470+
// extended section header index.
471+
if (!shndx_data)
472+
shndx_data = new Outbuffer(50 * sizeof(Elf64_Word));
473+
// fill with zeros up to symbol_idx
474+
const size_t shndx_idx = shndx_data->size() / sizeof(Elf64_Word);
475+
shndx_data->writezeros((symbol_idx - shndx_idx) * sizeof(Elf64_Word));
476+
477+
shndx_data->write32(sec);
478+
sec = SHN_XINDEX;
479+
}
480+
464481
if (I64)
465482
{
466483
if (!SYMbuf)
@@ -539,6 +556,14 @@ static IDXSEC elf_newsection2(
539556
{ SECbuf = new Outbuffer(4 * sizeof(Elf32_Shdr));
540557
SECbuf->reserve(16 * sizeof(Elf32_Shdr));
541558
}
559+
if (section_cnt == SHN_LORESERVE)
560+
{ // insert dummy null sections to skip reserved section indices
561+
section_cnt = SHN_HIRESERVE + 1;
562+
SECbuf->writezeros((SHN_HIRESERVE + 1 - SHN_LORESERVE) * sizeof(sec));
563+
// shndx itself becomes the first section with an extended index
564+
IDXSTR namidx = Obj::addstr(section_names, ".symtab_shndx");
565+
elf_newsection2(namidx,SHT_SYMTAB_SHNDX,0,0,0,0,SHN_SYMTAB,0,4,4);
566+
}
542567
SECbuf->write((void *)&sec, sizeof(sec));
543568
return section_cnt++;
544569
}
@@ -702,9 +727,9 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname)
702727
// name,type,flags,addr,offset,size,link,info,addralign,entsize
703728
elf_newsection2(0, SHT_NULL, 0, 0,0,0,0,0, 0,0);
704729
elf_newsection2(NAMIDX_TEXT,SHT_PROGDEF,SHF_ALLOC|SHF_EXECINSTR,0,0,0,0,0, 4,0);
705-
elf_newsection2(NAMIDX_RELTEXT,SHT_RELA, 0,0,0,0,SHI_SYMTAB, SHI_TEXT, 8,0x18);
730+
elf_newsection2(NAMIDX_RELTEXT,SHT_RELA, 0,0,0,0,SHN_SYMTAB, SHN_TEXT, 8,0x18);
706731
elf_newsection2(NAMIDX_DATA,SHT_PROGDEF,SHF_ALLOC|SHF_WRITE, 0,0,0,0,0, 8,0);
707-
elf_newsection2(NAMIDX_RELDATA64,SHT_RELA, 0,0,0,0,SHI_SYMTAB, SHI_DATA, 8,0x18);
732+
elf_newsection2(NAMIDX_RELDATA64,SHT_RELA, 0,0,0,0,SHN_SYMTAB, SHN_DATA, 8,0x18);
708733
elf_newsection2(NAMIDX_BSS, SHT_NOBITS,SHF_ALLOC|SHF_WRITE, 0,0,0,0,0, 16,0);
709734
elf_newsection2(NAMIDX_RODATA,SHT_PROGDEF,SHF_ALLOC, 0,0,0,0,0, 16,0);
710735
elf_newsection2(NAMIDX_STRTAB,SHT_STRTAB, 0, 0,0,0,0,0, 1,0);
@@ -748,9 +773,9 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname)
748773
// name,type,flags,addr,offset,size,link,info,addralign,entsize
749774
elf_newsection2(0, SHT_NULL, 0, 0,0,0,0,0, 0,0);
750775
elf_newsection2(NAMIDX_TEXT,SHT_PROGDEF,SHF_ALLOC|SHF_EXECINSTR,0,0,0,0,0, 16,0);
751-
elf_newsection2(NAMIDX_RELTEXT,SHT_REL, 0,0,0,0,SHI_SYMTAB, SHI_TEXT, 4,8);
776+
elf_newsection2(NAMIDX_RELTEXT,SHT_REL, 0,0,0,0,SHN_SYMTAB, SHN_TEXT, 4,8);
752777
elf_newsection2(NAMIDX_DATA,SHT_PROGDEF,SHF_ALLOC|SHF_WRITE, 0,0,0,0,0, 4,0);
753-
elf_newsection2(NAMIDX_RELDATA,SHT_REL, 0,0,0,0,SHI_SYMTAB, SHI_DATA, 4,8);
778+
elf_newsection2(NAMIDX_RELDATA,SHT_REL, 0,0,0,0,SHN_SYMTAB, SHN_DATA, 4,8);
754779
elf_newsection2(NAMIDX_BSS, SHT_NOBITS,SHF_ALLOC|SHF_WRITE, 0,0,0,0,0, 32,0);
755780
elf_newsection2(NAMIDX_RODATA,SHT_PROGDEF,SHF_ALLOC, 0,0,0,0,0, 1,0);
756781
elf_newsection2(NAMIDX_STRTAB,SHT_STRTAB, 0, 0,0,0,0,0, 1,0);
@@ -777,37 +802,39 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname)
777802

778803
if (SYMbuf)
779804
SYMbuf->setsize(0);
805+
if (shndx_data)
806+
shndx_data->setsize(0);
780807
symbol_idx = 0;
781808
local_cnt = 0;
782809
// The symbols that every object file has
783810
elf_addsym(0, 0, 0, STT_NOTYPE, STB_LOCAL, 0);
784-
elf_addsym(0, 0, 0, STT_FILE, STB_LOCAL, SHT_ABS); // STI_FILE
785-
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHI_TEXT); // STI_TEXT
786-
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHI_DATA); // STI_DATA
787-
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHI_BSS); // STI_BSS
788-
elf_addsym(0, 0, 0, STT_NOTYPE, STB_LOCAL, SHI_TEXT); // STI_GCC
789-
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHI_RODAT); // STI_RODAT
790-
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHI_NOTE); // STI_NOTE
791-
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHI_COM); // STI_COM
811+
elf_addsym(0, 0, 0, STT_FILE, STB_LOCAL, SHN_ABS); // STI_FILE
812+
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_TEXT); // STI_TEXT
813+
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_DATA); // STI_DATA
814+
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_BSS); // STI_BSS
815+
elf_addsym(0, 0, 0, STT_NOTYPE, STB_LOCAL, SHN_TEXT); // STI_GCC
816+
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_RODAT); // STI_RODAT
817+
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_NOTE); // STI_NOTE
818+
elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_COM); // STI_COM
792819

793820
// Initialize output buffers for CODE, DATA and COMMENTS
794821
// (NOTE not supported, BSS not required)
795822

796823
seg_count = 0;
797824

798-
elf_getsegment2(SHI_TEXT, STI_TEXT, SHI_RELTEXT);
825+
elf_getsegment2(SHN_TEXT, STI_TEXT, SHN_RELTEXT);
799826
assert(SegData[CODE]->SDseg == CODE);
800827

801-
elf_getsegment2(SHI_DATA, STI_DATA, SHI_RELDATA);
828+
elf_getsegment2(SHN_DATA, STI_DATA, SHN_RELDATA);
802829
assert(SegData[DATA]->SDseg == DATA);
803830

804-
elf_getsegment2(SHI_RODAT, STI_RODAT, 0);
831+
elf_getsegment2(SHN_RODAT, STI_RODAT, 0);
805832
assert(SegData[CDATA]->SDseg == CDATA);
806833

807-
elf_getsegment2(SHI_BSS, STI_BSS, 0);
834+
elf_getsegment2(SHN_BSS, STI_BSS, 0);
808835
assert(SegData[UDATA]->SDseg == UDATA);
809836

810-
elf_getsegment2(SHI_COM, STI_COM, 0);
837+
elf_getsegment2(SHN_COM, STI_COM, 0);
811838
assert(SegData[COMD]->SDseg == COMD);
812839

813840
if (config.fulltypes)
@@ -927,6 +954,24 @@ void *elf_renumbersyms()
927954
}
928955
}
929956

957+
// Reorder extended section header indices
958+
if (shndx_data && shndx_data->size())
959+
{
960+
// fill with zeros up to symbol_idx
961+
const size_t shndx_idx = shndx_data->size() / sizeof(Elf64_Word);
962+
shndx_data->writezeros((symbol_idx - shndx_idx) * sizeof(Elf64_Word));
963+
964+
Elf64_Word *old_buf = (Elf64_Word *)shndx_data->buf;
965+
Elf64_Word *tmp_buf = (Elf64_Word *)util_malloc(sizeof(Elf64_Word), symbol_idx);
966+
for (SYMIDX old_idx = 0; old_idx < symbol_idx; ++old_idx)
967+
{
968+
const SYMIDX new_idx = sym_map[old_idx];
969+
tmp_buf[new_idx] = old_buf[old_idx];
970+
}
971+
memcpy(old_buf, tmp_buf, sizeof(Elf64_Word) * symbol_idx);
972+
util_free(tmp_buf);
973+
}
974+
930975
// Renumber the relocations
931976
for (int i = 1; i <= seg_count; i++)
932977
{ // Map indicies in the segment table
@@ -938,7 +983,7 @@ void *elf_renumbersyms()
938983
unsigned oidx = SecHdrTab[pseg->SDshtidx].sh_info;
939984
assert(oidx < symbol_idx);
940985
// we only have one symbol table
941-
assert(SecHdrTab[pseg->SDshtidx].sh_link == SHI_SYMTAB);
986+
assert(SecHdrTab[pseg->SDshtidx].sh_link == SHN_SYMTAB);
942987
SecHdrTab[pseg->SDshtidx].sh_info = sym_map[oidx];
943988
}
944989

@@ -1064,8 +1109,13 @@ void Obj::term(const char *objfilename)
10641109
};
10651110
int hdrsize = I64 ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Hdr);
10661111

1067-
elf_header.e_shnum = section_cnt;
1068-
elf_header.e_shstrndx = SHI_SECNAMES;
1112+
if (section_cnt < SHN_LORESERVE)
1113+
elf_header.e_shnum = section_cnt;
1114+
else
1115+
{ elf_header.e_shnum = SHN_UNDEF;
1116+
SecHdrTab[0].sh_size = section_cnt;
1117+
}
1118+
elf_header.e_shstrndx = SHN_SECNAMES;
10691119
fobjbuf->writezeros(hdrsize);
10701120

10711121
// Walk through sections determining size and file offsets
@@ -1139,7 +1189,7 @@ void Obj::term(const char *objfilename)
11391189

11401190
if (comment_data)
11411191
{
1142-
sechdr = &SecHdrTab[SHI_COM]; // Comments
1192+
sechdr = &SecHdrTab[SHN_COM]; // Comments
11431193
sechdr->sh_size = comment_data->size();
11441194
sechdr->sh_offset = foffset;
11451195
fobjbuf->write(comment_data->buf, sechdr->sh_size);
@@ -1149,7 +1199,7 @@ void Obj::term(const char *objfilename)
11491199
//
11501200
// Then output string table for section names
11511201
//
1152-
sechdr = &SecHdrTab[SHI_SECNAMES]; // Section Names
1202+
sechdr = &SecHdrTab[SHN_SECNAMES]; // Section Names
11531203
sechdr->sh_size = section_names->size();
11541204
sechdr->sh_offset = foffset;
11551205
//dbg_printf("section names offset %d\n",foffset);
@@ -1160,19 +1210,29 @@ void Obj::term(const char *objfilename)
11601210
// Symbol table and string table for symbols next
11611211
//
11621212
//dbg_printf("output symbol table size %d\n",SYMbuf->size());
1163-
sechdr = &SecHdrTab[SHI_SYMTAB]; // Symbol Table
1213+
sechdr = &SecHdrTab[SHN_SYMTAB]; // Symbol Table
11641214
sechdr->sh_size = SYMbuf->size();
11651215
sechdr->sh_entsize = I64 ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym);
1166-
sechdr->sh_link = SHI_STRINGS;
1216+
sechdr->sh_link = SHN_STRINGS;
11671217
sechdr->sh_info = local_cnt;
11681218
foffset = elf_align(4,foffset);
11691219
sechdr->sh_offset = foffset;
11701220
fobjbuf->write(symtab, sechdr->sh_size);
11711221
foffset += sechdr->sh_size;
11721222
util_free(symtab);
11731223

1224+
if (shndx_data && shndx_data->size())
1225+
{
1226+
assert(section_cnt >= secidx_shndx);
1227+
sechdr = &SecHdrTab[secidx_shndx];
1228+
sechdr->sh_size = shndx_data->size();
1229+
sechdr->sh_offset = foffset;
1230+
fobjbuf->write(shndx_data->buf, sechdr->sh_size);
1231+
foffset += sechdr->sh_size;
1232+
}
1233+
11741234
//dbg_printf("output section strings size 0x%x,offset 0x%x\n",symtab_strings->size(),foffset);
1175-
sechdr = &SecHdrTab[SHI_STRINGS]; // Symbol Strings
1235+
sechdr = &SecHdrTab[SHN_STRINGS]; // Symbol Strings
11761236
sechdr->sh_size = symtab_strings->size();
11771237
sechdr->sh_offset = foffset;
11781238
fobjbuf->write(symtab_strings->buf, sechdr->sh_size);
@@ -1435,7 +1495,7 @@ void obj_filename(const char *modname)
14351495
{
14361496
//dbg_printf("obj_filename(char *%s)\n",modname);
14371497
unsigned strtab_idx = Obj::addstr(symtab_strings,modname);
1438-
elf_addsym(strtab_idx,0,0,STT_FILE,STB_LOCAL,SHT_ABS);
1498+
elf_addsym(strtab_idx,0,0,STT_FILE,STB_LOCAL,SHN_ABS);
14391499
}
14401500

14411501
/*******************************
@@ -2177,7 +2237,7 @@ int Obj::external_def(const char *name)
21772237
//dbg_printf("Obj::external_def('%s')\n",name);
21782238
assert(name);
21792239
IDXSTR namidx = Obj::addstr(symtab_strings,name);
2180-
IDXSYM symidx = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_GLOBAL, SHT_UNDEF);
2240+
IDXSYM symidx = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_GLOBAL, SHN_UNDEF);
21812241
return symidx;
21822242
}
21832243

@@ -2205,14 +2265,14 @@ int Obj::external(Symbol *s)
22052265
if (s->Sscope && !tyfunc(s->ty()))
22062266
{
22072267
symtype = STT_OBJECT;
2208-
sectype = SHT_COMMON;
2268+
sectype = SHN_COMMON;
22092269
size = type_size(s->Stype);
22102270
}
22112271
else
22122272
#endif
22132273
{
22142274
symtype = STT_NOTYPE;
2215-
sectype = SHT_UNDEF;
2275+
sectype = SHN_UNDEF;
22162276
size = 0;
22172277
}
22182278
if (s->ty() & mTYthread)
@@ -2270,7 +2330,7 @@ int Obj::common_block(Symbol *s,targ_size_t size,targ_size_t count)
22702330
alignOffset(UDATA,size);
22712331
IDXSYM symidx = elf_addsym(namidx, SegData[UDATA]->SDoffset, size*count,
22722332
(s->ty() & mTYthread) ? STT_TLS : STT_OBJECT,
2273-
STB_WEAK, SHI_BSS);
2333+
STB_WEAK, SHN_BSS);
22742334
//dbg_printf("\tObj::common_block returning symidx %d\n",symidx);
22752335
s->Sseg = UDATA;
22762336
s->Sfl = FLudata;
@@ -2429,10 +2489,10 @@ void ElfObj::addrel(int seg, targ_size_t offset, unsigned type,
24292489
if (segdata->SDrel->size() == 0)
24302490
{ IDXSEC relidx;
24312491

2432-
if (secidx == SHI_TEXT)
2433-
relidx = SHI_RELTEXT;
2434-
else if (secidx == SHI_DATA)
2435-
relidx = SHI_RELDATA;
2492+
if (secidx == SHN_TEXT)
2493+
relidx = SHN_RELTEXT;
2494+
else if (secidx == SHN_DATA)
2495+
relidx = SHN_RELDATA;
24362496
else
24372497
{
24382498
// Get the section name, and make a copy because
@@ -2453,15 +2513,15 @@ void ElfObj::addrel(int seg, targ_size_t offset, unsigned type,
24532513
* Elf64_Shdr.
24542514
*/
24552515
Elf32_Shdr *relsec = &SecHdrTab[relidx];
2456-
relsec->sh_link = SHI_SYMTAB;
2516+
relsec->sh_link = SHN_SYMTAB;
24572517
relsec->sh_info = secidx;
24582518
relsec->sh_entsize = sizeof(Elf64_Rela);
24592519
relsec->sh_addralign = 8;
24602520
}
24612521
else
24622522
{
24632523
Elf32_Shdr *relsec = &SecHdrTab[relidx];
2464-
relsec->sh_link = SHI_SYMTAB;
2524+
relsec->sh_link = SHN_SYMTAB;
24652525
relsec->sh_info = secidx;
24662526
relsec->sh_entsize = sizeof(Elf32_Rel);
24672527
relsec->sh_addralign = 4;
@@ -2681,12 +2741,12 @@ int Obj::reftoident(int seg, targ_size_t offset, Symbol *s, targ_size_t val,
26812741
{ // identifier is defined somewhere else
26822742
if (I64)
26832743
{
2684-
if (SymbolTable64[s->Sxtrnnum].st_shndx != SHT_UNDEF)
2744+
if (SymbolTable64[s->Sxtrnnum].st_shndx != SHN_UNDEF)
26852745
external = FALSE;
26862746
}
26872747
else
26882748
{
2689-
if (SymbolTable[s->Sxtrnnum].st_shndx != SHT_UNDEF)
2749+
if (SymbolTable[s->Sxtrnnum].st_shndx != SHN_UNDEF)
26902750
external = FALSE;
26912751
}
26922752
}
@@ -3220,7 +3280,7 @@ static void obj_rtinit()
32203280

32213281
// use a weak reference for _d_dso_registry
32223282
namidx = ElfObj::addstr(symtab_strings, "_d_dso_registry");
3223-
const IDXSYM symidx = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_WEAK, SHT_UNDEF);
3283+
const IDXSYM symidx = elf_addsym(namidx, 0, 0, STT_NOTYPE, STB_WEAK, SHN_UNDEF);
32243284

32253285
if (config.flags3 & CFG3pic)
32263286
{
@@ -3345,7 +3405,7 @@ static void obj_rtinit()
33453405
// set group section infos
33463406
Offset(groupseg) = SegData[groupseg]->SDbuf->size();
33473407
Elf32_Shdr *p = MAP_SEG2SEC(groupseg);
3348-
p->sh_link = SHI_SYMTAB;
3408+
p->sh_link = SHN_SYMTAB;
33493409
p->sh_info = dso_rec; // set the dso_rec as group symbol
33503410
p->sh_entsize = sizeof(IDXSYM);
33513411
p->sh_size = Offset(groupseg);

0 commit comments

Comments
 (0)