mirror of
https://github.com/golang/go.git
synced 2026-02-04 09:55:06 +03:00
cmd/link: move pclntab out of relro section
The .gopclntab section should not have any relocations. Move it out of relro to regular rodata. Note that this is tested by tests like TestNoTextrel in cmd/cgo/internal/testshared. The existing test TestMachoSectionsReadOnly looks for sections in a Mach-O file that are read-only after relocations are applied (this is marked by a segment with a flags field set to 0x10). We remove the __gopclntab section, as that section is now read-only at all times, not only after relocating. For #76038 Change-Id: I7f837e423bf1e802509277f5dc7fdd1ed0228e32 Reviewed-on: https://go-review.googlesource.com/c/go/+/718065 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
committed by
Gopher Robot
parent
43b91e7abd
commit
ad3ccd92e4
@@ -1581,7 +1581,7 @@ func (state *dodataState) makeRelroForSharedLib(target *Link) {
|
||||
// the relro data.
|
||||
isRelro = true
|
||||
}
|
||||
case sym.SGOFUNC:
|
||||
case sym.SGOFUNC, sym.SPCLNTAB:
|
||||
// The only SGOFUNC symbols that contain relocations are .stkobj,
|
||||
// and their relocations are of type objabi.R_ADDROFF,
|
||||
// which always get resolved during linking.
|
||||
@@ -2119,6 +2119,21 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
|
||||
}
|
||||
}
|
||||
|
||||
/* gopclntab */
|
||||
sect = state.allocateNamedSectionAndAssignSyms(segro, ".gopclntab", sym.SPCLNTAB, sym.SRODATA, 04)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pcheader", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
|
||||
setCarrierSize(sym.SPCLNTAB, int64(sect.Length))
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB)
|
||||
}
|
||||
|
||||
/* read-only ELF, Mach-O sections */
|
||||
state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04)
|
||||
|
||||
@@ -2238,21 +2253,6 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
|
||||
state.checkdatsize(sym.SITABLINK)
|
||||
sect.Length = uint64(state.datsize) - sect.Vaddr
|
||||
|
||||
/* gopclntab */
|
||||
sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gopclntab"), sym.SPCLNTAB, sym.SRODATA, relroSecPerm)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pcheader", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect)
|
||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
|
||||
setCarrierSize(sym.SPCLNTAB, int64(sect.Length))
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB)
|
||||
}
|
||||
|
||||
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
|
||||
if state.datsize != int64(uint32(state.datsize)) {
|
||||
Errorf("read-only data segment too large: %d", state.datsize)
|
||||
|
||||
@@ -1250,11 +1250,12 @@ func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
|
||||
|
||||
func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
|
||||
// If main section is SHT_NOBITS, nothing to relocate.
|
||||
// Also nothing to relocate in .shstrtab or notes.
|
||||
// Also nothing to relocate in .shstrtab or notes or .gopclntab.
|
||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
||||
return nil
|
||||
}
|
||||
if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
|
||||
switch sect.Name {
|
||||
case ".shstrtab", ".tbss", ".gopclntab":
|
||||
return nil
|
||||
}
|
||||
if sect.Elfsect.(*ElfShdr).Type == uint32(elf.SHT_NOTE) {
|
||||
@@ -1469,6 +1470,7 @@ func (ctxt *Link) doelf() {
|
||||
}
|
||||
shstrtabAddstring(".elfdata")
|
||||
shstrtabAddstring(".rodata")
|
||||
shstrtabAddstring(".gopclntab")
|
||||
// See the comment about data.rel.ro.FOO section names in data.go.
|
||||
relro_prefix := ""
|
||||
if ctxt.UseRelro() {
|
||||
@@ -1477,7 +1479,6 @@ func (ctxt *Link) doelf() {
|
||||
}
|
||||
shstrtabAddstring(relro_prefix + ".typelink")
|
||||
shstrtabAddstring(relro_prefix + ".itablink")
|
||||
shstrtabAddstring(relro_prefix + ".gopclntab")
|
||||
|
||||
if ctxt.IsExternal() {
|
||||
*FlagD = true
|
||||
@@ -1486,7 +1487,6 @@ func (ctxt *Link) doelf() {
|
||||
shstrtabAddstring(elfRelType + ".rodata")
|
||||
shstrtabAddstring(elfRelType + relro_prefix + ".typelink")
|
||||
shstrtabAddstring(elfRelType + relro_prefix + ".itablink")
|
||||
shstrtabAddstring(elfRelType + relro_prefix + ".gopclntab")
|
||||
shstrtabAddstring(elfRelType + ".noptrdata")
|
||||
shstrtabAddstring(elfRelType + ".data")
|
||||
if ctxt.UseRelro() {
|
||||
|
||||
@@ -408,7 +408,7 @@ func TestElfBindNow(t *testing.T) {
|
||||
}
|
||||
|
||||
// This program is intended to be just big/complicated enough that
|
||||
// we wind up with decent-sized .data.rel.ro.{typelink,itablink,gopclntab}
|
||||
// we wind up with decent-sized .data.rel.ro.{typelink,itablink}
|
||||
// sections.
|
||||
const ifacecallsProg = `
|
||||
package main
|
||||
|
||||
@@ -37,14 +37,14 @@ func TestMachoSectionsReadOnly(t *testing.T) {
|
||||
args: []string{"-ldflags", "-linkmode=internal"},
|
||||
prog: prog,
|
||||
mustInternalLink: true,
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink", "__gopclntab"},
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink"},
|
||||
},
|
||||
{
|
||||
name: "linkmode-external",
|
||||
args: []string{"-ldflags", "-linkmode=external"},
|
||||
prog: prog,
|
||||
mustHaveCGO: true,
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink", "__gopclntab"},
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink"},
|
||||
},
|
||||
{
|
||||
name: "cgo-linkmode-internal",
|
||||
@@ -52,14 +52,14 @@ func TestMachoSectionsReadOnly(t *testing.T) {
|
||||
prog: progC,
|
||||
mustHaveCGO: true,
|
||||
mustInternalLink: true,
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink", "__gopclntab"},
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink"},
|
||||
},
|
||||
{
|
||||
name: "cgo-linkmode-external",
|
||||
args: []string{"-ldflags", "-linkmode=external"},
|
||||
prog: progC,
|
||||
mustHaveCGO: true,
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink", "__gopclntab"},
|
||||
wantSecsRO: []string{"__got", "__rodata", "__itablink", "__typelink"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -111,7 +111,8 @@ func TestMachoSectionsReadOnly(t *testing.T) {
|
||||
|
||||
for _, wsroname := range test.wantSecsRO {
|
||||
// Now walk the sections. Section should be part of
|
||||
// some segment that is readonly.
|
||||
// some segment that is made readonly after
|
||||
// relocations are appied.
|
||||
var wsro *macho.Section
|
||||
foundRO := false
|
||||
for _, s := range machoFile.Sections {
|
||||
|
||||
@@ -64,6 +64,7 @@ const (
|
||||
SRODATAFIPSEND // End of FIPS read-only data.
|
||||
SRODATAEND // End of read-only data.
|
||||
SFUNCTAB // Appears to be unused, except for runtime.etypes.
|
||||
SPCLNTAB // Pclntab data.
|
||||
SELFROSECT // ELF read-only data: relocs, dynamic linking info.
|
||||
|
||||
// Read-only, non-executable, dynamically relocatable segment.
|
||||
@@ -91,7 +92,6 @@ const (
|
||||
|
||||
STYPELINK // Type links.
|
||||
SITABLINK // Itab links.
|
||||
SPCLNTAB // Pclntab data.
|
||||
|
||||
// Allocated writable segment.
|
||||
SFirstWritable
|
||||
|
||||
@@ -27,19 +27,19 @@ func _() {
|
||||
_ = x[SRODATAFIPSEND-16]
|
||||
_ = x[SRODATAEND-17]
|
||||
_ = x[SFUNCTAB-18]
|
||||
_ = x[SELFROSECT-19]
|
||||
_ = x[STYPERELRO-20]
|
||||
_ = x[SSTRINGRELRO-21]
|
||||
_ = x[SGOSTRINGRELRO-22]
|
||||
_ = x[SGOFUNCRELRO-23]
|
||||
_ = x[SGCBITSRELRO-24]
|
||||
_ = x[SRODATARELRO-25]
|
||||
_ = x[SFUNCTABRELRO-26]
|
||||
_ = x[SELFRELROSECT-27]
|
||||
_ = x[SMACHORELROSECT-28]
|
||||
_ = x[STYPELINK-29]
|
||||
_ = x[SITABLINK-30]
|
||||
_ = x[SPCLNTAB-31]
|
||||
_ = x[SPCLNTAB-19]
|
||||
_ = x[SELFROSECT-20]
|
||||
_ = x[STYPERELRO-21]
|
||||
_ = x[SSTRINGRELRO-22]
|
||||
_ = x[SGOSTRINGRELRO-23]
|
||||
_ = x[SGOFUNCRELRO-24]
|
||||
_ = x[SGCBITSRELRO-25]
|
||||
_ = x[SRODATARELRO-26]
|
||||
_ = x[SFUNCTABRELRO-27]
|
||||
_ = x[SELFRELROSECT-28]
|
||||
_ = x[SMACHORELROSECT-29]
|
||||
_ = x[STYPELINK-30]
|
||||
_ = x[SITABLINK-31]
|
||||
_ = x[SFirstWritable-32]
|
||||
_ = x[SBUILDINFO-33]
|
||||
_ = x[SFIPSINFO-34]
|
||||
@@ -90,9 +90,9 @@ func _() {
|
||||
_ = x[SSEHSECT-79]
|
||||
}
|
||||
|
||||
const _SymKind_name = "SxxxSTEXTSTEXTFIPSSTARTSTEXTFIPSSTEXTFIPSENDSTEXTENDSELFRXSECTSMACHOPLTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASRODATAFIPSSTARTSRODATAFIPSSRODATAFIPSENDSRODATAENDSFUNCTABSELFROSECTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSELFRELROSECTSMACHORELROSECTSTYPELINKSITABLINKSPCLNTABSFirstWritableSBUILDINFOSFIPSINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASNOPTRDATAFIPSSTARTSNOPTRDATAFIPSSNOPTRDATAFIPSENDSNOPTRDATAENDSINITARRSDATASDATAFIPSSTARTSDATAFIPSSDATAFIPSENDSDATAENDSXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_8BIT_COUNTERSCOVERAGE_COUNTERSCOVERAGE_AUXVARSTLSBSSSFirstUnallocatedSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSDWARFADDRSSEHUNWINDINFOSSEHSECT"
|
||||
const _SymKind_name = "SxxxSTEXTSTEXTFIPSSTARTSTEXTFIPSSTEXTFIPSENDSTEXTENDSELFRXSECTSMACHOPLTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASRODATAFIPSSTARTSRODATAFIPSSRODATAFIPSENDSRODATAENDSFUNCTABSPCLNTABSELFROSECTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSELFRELROSECTSMACHORELROSECTSTYPELINKSITABLINKSFirstWritableSBUILDINFOSFIPSINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASNOPTRDATAFIPSSTARTSNOPTRDATAFIPSSNOPTRDATAFIPSENDSNOPTRDATAENDSINITARRSDATASDATAFIPSSTARTSDATAFIPSSDATAFIPSENDSDATAENDSXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_8BIT_COUNTERSCOVERAGE_COUNTERSCOVERAGE_AUXVARSTLSBSSSFirstUnallocatedSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSDWARFADDRSSEHUNWINDINFOSSEHSECT"
|
||||
|
||||
var _SymKind_index = [...]uint16{0, 4, 9, 23, 32, 44, 52, 62, 71, 76, 83, 92, 99, 106, 113, 129, 140, 154, 164, 172, 182, 192, 204, 218, 230, 242, 254, 267, 280, 295, 304, 313, 321, 335, 345, 354, 362, 368, 377, 385, 392, 402, 421, 435, 452, 465, 473, 478, 492, 501, 513, 521, 530, 534, 543, 566, 583, 599, 606, 623, 628, 640, 652, 669, 686, 696, 704, 713, 723, 735, 746, 755, 767, 777, 786, 797, 806, 817, 827, 841, 849}
|
||||
var _SymKind_index = [...]uint16{0, 4, 9, 23, 32, 44, 52, 62, 71, 76, 83, 92, 99, 106, 113, 129, 140, 154, 164, 172, 180, 190, 200, 212, 226, 238, 250, 262, 275, 288, 303, 312, 321, 335, 345, 354, 362, 368, 377, 385, 392, 402, 421, 435, 452, 465, 473, 478, 492, 501, 513, 521, 530, 534, 543, 566, 583, 599, 606, 623, 628, 640, 652, 669, 686, 696, 704, 713, 723, 735, 746, 755, 767, 777, 786, 797, 806, 817, 827, 841, 849}
|
||||
|
||||
func (i SymKind) String() string {
|
||||
if i >= SymKind(len(_SymKind_index)-1) {
|
||||
|
||||
Reference in New Issue
Block a user