diff --git a/src/backend/elfobj.c b/src/backend/elfobj.c index d7fbf7c20e04..edf5ec0869ca 100644 --- a/src/backend/elfobj.c +++ b/src/backend/elfobj.c @@ -634,23 +634,11 @@ symbol *Obj::sym_cdata(tym_t ty,char *p,int len) int Obj::data_readonly(char *p, int len, int *pseg) { - int oldoff; - /*if (OPT_IS_SET(OPTfwritable_strings)) - { - oldoff = Doffset; - SegData[DATA]->SDbuf->reserve(len); - SegData[DATA]->SDbuf->writen(p,len); - Doffset += len; - *pseg = DATA; - } - else*/ - { - oldoff = CDoffset; - SegData[CDATA]->SDbuf->reserve(len); - SegData[CDATA]->SDbuf->writen(p,len); - CDoffset += len; - *pseg = CDATA; - } + int oldoff = CDoffset; + SegData[CDATA]->SDbuf->reserve(len); + SegData[CDATA]->SDbuf->writen(p,len); + CDoffset += len; + *pseg = CDATA; return oldoff; } diff --git a/src/backend/machobj.c b/src/backend/machobj.c index 02ba7f269b45..15018d6e2f43 100644 --- a/src/backend/machobj.c +++ b/src/backend/machobj.c @@ -162,6 +162,12 @@ static IDXSTR extdef; int seg_data::isCode() { + // The codegen assumes that code->data references are indirect, + // but when CDATA is treated as code reftoident will emit a direct + // relocation. + if (this == SegData[CDATA]) + return false; + if (I64) { //printf("SDshtidx = %d, x%x\n", SDshtidx, SecHdrTab64[SDshtidx].flags); @@ -384,23 +390,11 @@ symbol * Obj::sym_cdata(tym_t ty,char *p,int len) int Obj::data_readonly(char *p, int len, int *pseg) { - int oldoff; - if (I64) - { - oldoff = Doffset; - SegData[DATA]->SDbuf->reserve(len); - SegData[DATA]->SDbuf->writen(p,len); - Doffset += len; - *pseg = DATA; - } - else - { - oldoff = CDoffset; - SegData[CDATA]->SDbuf->reserve(len); - SegData[CDATA]->SDbuf->writen(p,len); - CDoffset += len; - *pseg = CDATA; - } + int oldoff = CDoffset; + SegData[CDATA]->SDbuf->reserve(len); + SegData[CDATA]->SDbuf->writen(p,len); + CDoffset += len; + *pseg = CDATA; return oldoff; } @@ -482,9 +476,10 @@ Obj *Obj::init(Outbuffer *objbuf, const char *filename, const char *csegname) seg_count = 0; int align = I64 ? 4 : 2; // align to 16 bytes for floating point MachObj::getsegment("__text", "__TEXT", 2, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS); - MachObj::getsegment("__data", "__DATA", align, S_REGULAR); // DATA + MachObj::getsegment("__data", "__DATA", align, S_REGULAR); // DATA MachObj::getsegment("__const", "__TEXT", 2, S_REGULAR); // CDATA MachObj::getsegment("__bss", "__DATA", 4, S_ZEROFILL); // UDATA + MachObj::getsegment("__const", "__DATA", align, S_REGULAR); // CDATAREL if (config.fulltypes) dwarf_initfile(filename); diff --git a/src/backend/out.c b/src/backend/out.c index 55cc1ee988d4..d23362b1a5c1 100644 --- a/src/backend/out.c +++ b/src/backend/out.c @@ -514,7 +514,7 @@ void outcommon(symbol *s,targ_size_t n) void out_readonly(symbol *s) { // The default is DATA -#if ELFOBJ +#if ELFOBJ || MACHOBJ /* Cannot have pointers in CDATA when compiling PIC code, because * they require dynamic relocations of the read-only segment. * Instead use the .data.rel.ro section. See Bugzilla 11171. @@ -524,12 +524,6 @@ void out_readonly(symbol *s) else s->Sseg = CDATA; #endif -#if MACHOBJ - /* Because of PIC and CDATA being in the _TEXT segment; - * cannot have pointers in CDATA. - * Should check s->Sdt and make it CDATA if it has no pointers. - */ -#endif #if OMFOBJ // Haven't really worked out where immutable read-only data can go. #endif