From 249844e1d3c17927d6022c07487b2880a6cad5fd Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Tue, 4 Feb 2014 01:49:47 +0100 Subject: [PATCH] use .data.rel.ro segment for constant data with relocations - The runtime linker will mark this as read only after relocations are processed. --- src/backend/cdef.h | 1 + src/backend/elfobj.c | 24 ++++++++++++++++++------ src/backend/out.c | 4 +++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/backend/cdef.h b/src/backend/cdef.h index 945b989b7294..140390285669 100644 --- a/src/backend/cdef.h +++ b/src/backend/cdef.h @@ -575,6 +575,7 @@ typedef targ_uns targ_size_t; /* size_t for the target machine */ #define DATA 2 /* initialized data */ #define CDATA 3 /* constant data */ #define UDATA 4 /* uninitialized data */ +#define CDATAREL 5 /* constant data with relocs */ #define UNKNOWN -1 /* unknown segment */ #define DGROUPIDX 1 /* group index of DGROUP */ diff --git a/src/backend/elfobj.c b/src/backend/elfobj.c index f0c7225c18f2..ff9bbb58d457 100644 --- a/src/backend/elfobj.c +++ b/src/backend/elfobj.c @@ -227,6 +227,8 @@ static int section_cnt; // Number of sections in table #define SHN_SECNAMES 9 #define SHN_COM 10 #define SHN_NOTE 11 +#define SHN_GNUSTACK 12 +#define SHN_CDATAREL 13 IDXSYM *mapsec2sym; #define S2S_INC 20 @@ -244,6 +246,7 @@ static int local_cnt; // Number of symbols with STB_LOCAL #define STI_RODAT 6 // Symbol for readonly data #define STI_NOTE 7 // Where note symbol table entry is #define STI_COM 8 +#define STI_CDATAREL 9 // Symbol for readonly data with relocations // NOTE: There seems to be a requirement that the read-only data have the // same symbol table index and section index. Use section NOTE as a place @@ -276,7 +279,7 @@ static const char compiler[] = "\0Digital Mars C/C++" // same section as initialized data or code, so section offsets should // be continuous when adding data. Fix-ups anywhere withing existing data. -#define COMD UDATA+1 +#define COMD CDATAREL+1 #define OB_SEG_SIZ 10 // initial number of segments supported #define OB_SEG_INC 10 // increment for additional segments @@ -696,7 +699,7 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) if (I64) { static char section_names_init64[] = - "\0.symtab\0.strtab\0.shstrtab\0.text\0.data\0.bss\0.note\0.comment\0.rodata\0.note.GNU-stack\0.rela.text\0.rela.data"; + "\0.symtab\0.strtab\0.shstrtab\0.text\0.data\0.bss\0.note\0.comment\0.rodata\0.note.GNU-stack\0.data.rel.ro\0.rela.text\0.rela.data"; #define NAMIDX_NONE 0 #define NAMIDX_SYMTAB 1 // .symtab #define NAMIDX_STRTAB 9 // .strtab @@ -708,9 +711,10 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) #define NAMIDX_COMMENT 50 // .comment #define NAMIDX_RODATA 59 // .rodata #define NAMIDX_GNUSTACK 67 // .note.GNU-stack - #define NAMIDX_RELTEXT 83 // .rel.text and .rela.text - #define NAMIDX_RELDATA 93 // .rel.data - #define NAMIDX_RELDATA64 94 // .rela.data + #define NAMIDX_CDATAREL 83 // .data.rel.ro + #define NAMIDX_RELTEXT 96 // .rel.text and .rela.text + #define NAMIDX_RELDATA 106 // .rel.data + #define NAMIDX_RELDATA64 107 // .rela.data if (section_names) section_names->setsize(sizeof(section_names_init64)); @@ -738,6 +742,7 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) elf_newsection2(NAMIDX_COMMENT, SHT_PROGDEF,0, 0,0,0,0,0, 1,0); elf_newsection2(NAMIDX_NOTE,SHT_NOTE, 0, 0,0,0,0,0, 1,0); elf_newsection2(NAMIDX_GNUSTACK,SHT_PROGDEF,0, 0,0,0,0,0, 1,0); + elf_newsection2(NAMIDX_CDATAREL,SHT_PROGDEF,SHF_ALLOC|SHF_WRITE,0,0,0,0,0, 16,0); IDXSTR namidx; namidx = NAMIDX_TEXT; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; @@ -752,11 +757,12 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) namidx = NAMIDX_COMMENT; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; namidx = NAMIDX_NOTE; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; namidx = NAMIDX_GNUSTACK; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; + namidx = NAMIDX_CDATAREL; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; } else { static char section_names_init[] = - "\0.symtab\0.strtab\0.shstrtab\0.text\0.data\0.bss\0.note\0.comment\0.rodata\0.note.GNU-stack\0.rel.text\0.rel.data"; + "\0.symtab\0.strtab\0.shstrtab\0.text\0.data\0.bss\0.note\0.comment\0.rodata\0.note.GNU-stack\0.data.rel.ro\0.rel.text\0.rel.data"; if (section_names) section_names->setsize(sizeof(section_names_init)); @@ -784,6 +790,7 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) elf_newsection2(NAMIDX_COMMENT, SHT_PROGDEF,0, 0,0,0,0,0, 1,0); elf_newsection2(NAMIDX_NOTE,SHT_NOTE, 0, 0,0,0,0,0, 1,0); elf_newsection2(NAMIDX_GNUSTACK,SHT_PROGDEF,0, 0,0,0,0,0, 1,0); + elf_newsection2(NAMIDX_CDATAREL,SHT_PROGDEF,SHF_ALLOC|SHF_WRITE,0,0,0,0,0, 1,0); IDXSTR namidx; namidx = NAMIDX_TEXT; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; @@ -798,6 +805,7 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) namidx = NAMIDX_COMMENT; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; namidx = NAMIDX_NOTE; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; namidx = NAMIDX_GNUSTACK; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; + namidx = NAMIDX_CDATAREL; *(IDXSTR *)section_names_hashtable->get(&namidx) = namidx; } if (SYMbuf) @@ -816,6 +824,7 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_RODAT); // STI_RODAT elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_NOTE); // STI_NOTE elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_COM); // STI_COM + elf_addsym(0, 0, 0, STT_SECTION, STB_LOCAL, SHN_CDATAREL); // STI_CDATAREL // Initialize output buffers for CODE, DATA and COMMENTS // (NOTE not supported, BSS not required) @@ -834,6 +843,9 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) elf_getsegment2(SHN_BSS, STI_BSS, 0); assert(SegData[UDATA]->SDseg == UDATA); + elf_getsegment2(SHN_CDATAREL, STI_CDATAREL, 0); + assert(SegData[CDATAREL]->SDseg == CDATAREL); + elf_getsegment2(SHN_COM, STI_COM, 0); assert(SegData[COMD]->SDseg == COMD); diff --git a/src/backend/out.c b/src/backend/out.c index 4ded01a0ef7b..55cc1ee988d4 100644 --- a/src/backend/out.c +++ b/src/backend/out.c @@ -519,7 +519,9 @@ void out_readonly(symbol *s) * they require dynamic relocations of the read-only segment. * Instead use the .data.rel.ro section. See Bugzilla 11171. */ - if (!(config.flags3 & CFG3pic && dtpointers(s->Sdt))) + if (config.flags3 & CFG3pic && dtpointers(s->Sdt)) + s->Sseg = CDATAREL; + else s->Sseg = CDATA; #endif #if MACHOBJ