]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fix XCOFF sections
authorClément Chigot <clement.chigot@atos.net>
Fri, 23 Nov 2018 10:17:36 +0000 (11:17 +0100)
committerIan Lance Taylor <iant@golang.org>
Mon, 26 Nov 2018 23:51:21 +0000 (23:51 +0000)
XCOFF files can't have multiples text or data sections. The name
of each type section must be .text, .data and .bss.

This commit also updates cmd/internal/objfile/xcoff.go to retrieve Go
sections using runtime symbols.

Change-Id: Ib6315f19dad2d154a4531fc6508e7cbd8bc94743
Reviewed-on: https://go-review.googlesource.com/c/151037
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/internal/objfile/xcoff.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/xcoff.go
src/cmd/link/internal/ppc64/asm.go

index c36b4362ba834f0c24a11d3e01c17727f2c9e4ec..f62a7edf89fa50f92a2a1d307a83f2116fefb090 100644 (file)
@@ -91,15 +91,11 @@ func (f *xcoffFile) pcln() (textStart uint64, symtab, pclntab []byte, err error)
        if sect := f.xcoff.Section(".text"); sect != nil {
                textStart = sect.VirtualAddress
        }
-       if sect := f.xcoff.Section(".gosymtab"); sect != nil {
-               if symtab, err = sect.Data(); err != nil {
-                       return 0, nil, nil, err
-               }
+       if pclntab, err = loadXCOFFTable(f.xcoff, "runtime.pclntab", "runtime.epclntab"); err != nil {
+               return 0, nil, nil, err
        }
-       if sect := f.xcoff.Section(".gopclntab"); sect != nil {
-               if pclntab, err = sect.Data(); err != nil {
-                       return 0, nil, nil, err
-               }
+       if symtab, err = loadXCOFFTable(f.xcoff, "runtime.symtab", "runtime.esymtab"); err != nil {
+               return 0, nil, nil, err
        }
        return textStart, symtab, pclntab, nil
 }
@@ -114,6 +110,42 @@ func (f *xcoffFile) text() (textStart uint64, text []byte, err error) {
        return
 }
 
+func findXCOFFSymbol(f *xcoff.File, name string) (*xcoff.Symbol, error) {
+       for _, s := range f.Symbols {
+               if s.Name != name {
+                       continue
+               }
+               if s.SectionNumber <= 0 {
+                       return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
+               }
+               if len(f.Sections) < int(s.SectionNumber) {
+                       return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
+               }
+               return s, nil
+       }
+       return nil, fmt.Errorf("no %s symbol found", name)
+}
+
+func loadXCOFFTable(f *xcoff.File, sname, ename string) ([]byte, error) {
+       ssym, err := findXCOFFSymbol(f, sname)
+       if err != nil {
+               return nil, err
+       }
+       esym, err := findXCOFFSymbol(f, ename)
+       if err != nil {
+               return nil, err
+       }
+       if ssym.SectionNumber != esym.SectionNumber {
+               return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
+       }
+       sect := f.Sections[ssym.SectionNumber-1]
+       data, err := sect.Data()
+       if err != nil {
+               return nil, err
+       }
+       return data[ssym.Value:esym.Value], nil
+}
+
 func (f *xcoffFile) goarch() string {
        switch f.xcoff.TargetMachine {
        case xcoff.U802TOCMAGIC:
index ef796b623aa093d29e2d4f55c9067b73f4d84e1c..367842e0c6e65ae8371eb147dabc85bfa8b0f265 100644 (file)
@@ -1708,10 +1708,6 @@ func (ctxt *Link) dodata() {
        }
        for _, sect := range Segdata.Sections {
                sect.Extnum = int16(n)
-               if ctxt.HeadType == objabi.Haix && (sect.Name == ".noptrdata" || sect.Name == ".bss") {
-                       // On AIX, "noptr" sections are merged with their "ptr" section
-                       continue
-               }
                n++
        }
        for _, sect := range Segdwarf.Sections {
index e39f1bb9f06674b65982f07fd986fc5cedc874ab..d04065851d35834e079f81b3ed2c7076cc69861c 100644 (file)
@@ -329,6 +329,14 @@ type XcoffLdRel64 struct {
        Lsymndx int32  // Loader-Section symbol table index
 }
 
+// xcoffLoaderReloc holds information about a relocation made by the loader.
+type xcoffLoaderReloc struct {
+       sym    *sym.Symbol
+       rel    *sym.Reloc
+       rtype  uint16
+       symndx int32
+}
+
 const (
        XCOFF_R_POS = 0x00 // A(sym) Positive Relocation
 )
@@ -340,19 +348,17 @@ type XcoffLdStr64 struct {
 
 // xcoffFile is used to build XCOFF file.
 type xcoffFile struct {
-       xfhdr        XcoffFileHdr64
-       xahdr        XcoffAoutHdr64
-       sections     []*XcoffScnHdr64
-       stringTable  xcoffStringTable
-       textSect     *XcoffScnHdr64
-       dataSect     *XcoffScnHdr64
-       bssSect      *XcoffScnHdr64
-       loaderSect   *XcoffScnHdr64
-       symtabOffset int64           // offset to the start of symbol table
-       symbolCount  uint32          // number of symbol table records written
-       dynLibraries map[string]int  // Dynamic libraries in .loader section. The integer represents its import file number (- 1)
-       dynSymbols   []*sym.Symbol   // Dynamic symbols in .loader section
-       loaderReloc  []*XcoffLdRel64 // Reloc that must be made inside loader
+       xfhdr           XcoffFileHdr64
+       xahdr           XcoffAoutHdr64
+       sections        []*XcoffScnHdr64
+       stringTable     xcoffStringTable
+       sectNameToScnum map[string]int16
+       loaderSize      uint64
+       symtabOffset    int64               // offset to the start of symbol table
+       symbolCount     uint32              // number of symbol table records written
+       dynLibraries    map[string]int      // Dynamic libraries in .loader section. The integer represents its import file number (- 1)
+       dynSymbols      []*sym.Symbol       // Dynamic symbols in .loader section
+       loaderReloc     []*xcoffLoaderReloc // Reloc that must be made inside loader
 }
 
 // Those values will latter be computed in XcoffInit
@@ -363,9 +369,7 @@ var (
 
 // Var used by XCOFF Generation algorithms
 var (
-       xfile      xcoffFile
-       loaderOff  uint64
-       loaderSize uint64
+       xfile xcoffFile
 )
 
 // xcoffStringTable is a XCOFF string table.
@@ -404,29 +408,17 @@ func (sect *XcoffScnHdr64) write(ctxt *Link) {
 }
 
 // addSection adds section to the XCOFF file f.
-func (f *xcoffFile) addSection(s *sym.Section) *XcoffScnHdr64 {
-       sect := &XcoffScnHdr64{
-               Spaddr:  s.Vaddr,
-               Svaddr:  s.Vaddr,
-               Ssize:   s.Length,
-               Sscnptr: s.Seg.Fileoff + s.Vaddr - s.Seg.Vaddr,
-       }
-       copy(sect.Sname[:], s.Name) // copy string to [8]byte ( pb if len(name) > 8 )
-       f.sections = append(f.sections, sect)
-       return sect
-}
-
-// addLoaderSection adds the loader section to the XCOFF file f.
-func (f *xcoffFile) addLoaderSection(size uint64, off uint64) *XcoffScnHdr64 {
+func (f *xcoffFile) addSection(name string, addr uint64, size uint64, fileoff uint64, flags uint32) *XcoffScnHdr64 {
        sect := &XcoffScnHdr64{
+               Spaddr:  addr,
+               Svaddr:  addr,
                Ssize:   size,
-               Sscnptr: off,
-               Sflags:  STYP_LOADER,
+               Sscnptr: fileoff,
+               Sflags:  flags,
        }
-       copy(sect.Sname[:], ".loader") // copy string to [8]byte ( pb if len(name) > 8
-       f.xahdr.Osnloader = int16(len(f.sections) + 1)
+       copy(sect.Sname[:], name) // copy string to [8]byte
        f.sections = append(f.sections, sect)
-       f.loaderSect = sect
+       f.sectNameToScnum[name] = int16(len(f.sections))
        return sect
 }
 
@@ -434,16 +426,8 @@ func (f *xcoffFile) addLoaderSection(size uint64, off uint64) *XcoffScnHdr64 {
 // This function is similar to addSection, but Dwarf section names
 // must be modified to conventional names and they are various subtypes.
 func (f *xcoffFile) addDwarfSection(s *sym.Section) *XcoffScnHdr64 {
-       sect := &XcoffScnHdr64{
-               Ssize:   s.Length,
-               Sscnptr: s.Seg.Fileoff + s.Vaddr - s.Seg.Vaddr,
-               Sflags:  STYP_DWARF,
-       }
        newName, subtype := xcoffGetDwarfSubtype(s.Name)
-       copy(sect.Sname[:], newName)
-       sect.Sflags |= subtype
-       f.sections = append(f.sections, sect)
-       return sect
+       return f.addSection(newName, 0, s.Length, s.Seg.Fileoff+s.Vaddr-s.Seg.Vaddr, STYP_DWARF|subtype)
 }
 
 // xcoffGetDwarfSubtype returns the XCOFF name of the DWARF section str
@@ -473,6 +457,27 @@ func xcoffGetDwarfSubtype(str string) (string, uint32) {
        return "", 0
 }
 
+// getXCOFFscnum returns the XCOFF section number of a Go section.
+func (f *xcoffFile) getXCOFFscnum(sect *sym.Section) int16 {
+       switch sect.Seg {
+       case &Segtext:
+               return f.sectNameToScnum[".text"]
+       case &Segdata:
+               if sect.Name == ".noptrdata" || sect.Name == ".data" {
+                       return f.sectNameToScnum[".data"]
+               }
+               if sect.Name == ".noptrbss" || sect.Name == ".bss" {
+                       return f.sectNameToScnum[".bss"]
+               }
+               Errorf(nil, "unknown XCOFF segment data section: %s", sect.Name)
+       case &Segdwarf:
+               name, _ := xcoffGetDwarfSubtype(sect.Name)
+               return f.sectNameToScnum[name]
+       }
+       Errorf(nil, "getXCOFFscnum not implemented for section %s", sect.Name)
+       return -1
+}
+
 // Xcoffinit initialised some internal value and setups
 // already known header information
 func Xcoffinit(ctxt *Link) {
@@ -561,7 +566,7 @@ func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint6
                        Nvalue:  currDwscnoff[sect.Name],
                        Noffset: uint32(f.stringTable.add(name)),
                        Nsclass: C_DWARF,
-                       Nscnum:  sect.Extnum,
+                       Nscnum:  f.getXCOFFscnum(sect),
                        Nnumaux: 1,
                }
                f.writeSymbol(ctxt.Out, ctxt.Arch.ByteOrder, s)
@@ -660,7 +665,7 @@ func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []interface{} {
                        xfile.updatePreviousFile(ctxt, false)
                        currSymSrcFile.name = x.File
                        currSymSrcFile.fileSymNb = f.symbolCount
-                       f.writeSymbolNewFile(ctxt, x.File, uint64(x.Value), x.Sect.Extnum)
+                       f.writeSymbolNewFile(ctxt, x.File, uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
                }
        }
 
@@ -668,7 +673,7 @@ func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []interface{} {
                Nsclass: C_EXT,
                Noffset: uint32(xfile.stringTable.add(x.Name)),
                Nvalue:  uint64(x.Value),
-               Nscnum:  x.Sect.Extnum,
+               Nscnum:  f.getXCOFFscnum(x.Sect),
                Ntype:   SYM_TYPE_FUNC,
                Nnumaux: 2,
        }
@@ -726,7 +731,7 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64,
                                Nsclass: C_HIDEXT,
                                Noffset: uint32(xfile.stringTable.add(str)),
                                Nvalue:  uint64(x.Value),
-                               Nscnum:  x.Sect.Extnum,
+                               Nscnum:  xfile.getXCOFFscnum(x.Sect),
                                Ntype:   SYM_TYPE_FUNC,
                                Nnumaux: 1,
                        }
@@ -749,7 +754,7 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64,
                        Nsclass: C_EXT,
                        Noffset: uint32(xfile.stringTable.add(str)),
                        Nvalue:  uint64(x.Value),
-                       Nscnum:  x.Sect.Extnum,
+                       Nscnum:  xfile.getXCOFFscnum(x.Sect),
                        Nnumaux: 1,
                }
 
@@ -798,9 +803,8 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64,
 }
 
 // Generate XCOFF Symbol table and XCOFF String table
-func Asmaixsym(ctxt *Link) {
+func (f *xcoffFile) asmaixsym(ctxt *Link) {
        // write symbol table
-       xfile.symtabOffset = ctxt.Out.Offset()
        genasmsym(ctxt, putaixsym)
 
        // update last file Svalue
@@ -852,16 +856,16 @@ func xcoffaddloaderreloc(ctxt *Link, s *sym.Symbol, r *sym.Reloc) {
                Errorf(s, "cannot have a relocation in a text section with a data symbol: %s ", r.Sym.Name)
        }
 
-       ldr := &XcoffLdRel64{
-               Lvaddr:  uint64(s.Value + int64(r.Off)),
-               Lrsecnm: s.Sect.Extnum,
+       ldr := &xcoffLoaderReloc{
+               sym: s,
+               rel: r,
        }
 
        switch r.Type {
        case objabi.R_ADDR:
                // Relocation of a .data symbol
-               ldr.Lrtype = 0x3F<<8 + XCOFF_R_POS
-               ldr.Lsymndx = 1 // .data
+               ldr.rtype = 0x3F<<8 + XCOFF_R_POS
+               ldr.symndx = 1 // .data
        default:
                Errorf(s, "unexpected .loader relocation to symbol: %s (type: %s)", r.Sym.Name, r.Type.String())
        }
@@ -917,9 +921,8 @@ func (ctxt *Link) doxcoff() {
 // according to information retrieved in xfile object.
 
 // Create loader section and returns its size
-func Loaderblk(ctxt *Link, off uint64) uint64 {
+func Loaderblk(ctxt *Link, off uint64) {
        xfile.writeLdrScn(ctxt, off)
-       return loaderSize
 }
 
 func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
@@ -948,7 +951,7 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
        lds := &XcoffLdSym64{
                Lvalue:  uint64(ep.Value),
                Loffset: uint32(stlen + 2), // +2 because it must have the first byte of the symbol not its size field
-               Lscnum:  ep.Sect.Extnum,
+               Lscnum:  f.getXCOFFscnum(ep.Sect),
                Lsmtype: XTY_ENT | XTY_SD,
                Lsmclas: XMC_DS,
                Lifile:  0,
@@ -984,7 +987,7 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
                ldr := &XcoffLdRel64{
                        Lvaddr:  uint64(s.Value),
                        Lrtype:  0x3F00,
-                       Lrsecnm: s.Sect.Extnum,
+                       Lrsecnm: f.getXCOFFscnum(s.Sect),
                        Lsymndx: int32(nbldsym),
                }
                dynimpreloc = append(dynimpreloc, ldr)
@@ -1000,14 +1003,26 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
        ldr := &XcoffLdRel64{
                Lvaddr:  uint64(ep.Value),
                Lrtype:  0x3F00,
-               Lrsecnm: ep.Sect.Extnum,
+               Lrsecnm: f.getXCOFFscnum(ep.Sect),
                Lsymndx: 0,
        }
        off += 16
        reloctab = append(reloctab, ldr)
 
        off += uint64(16 * len(f.loaderReloc))
-       reloctab = append(reloctab, (f.loaderReloc)...)
+       for _, r := range f.loaderReloc {
+               ldr = &XcoffLdRel64{
+                       Lvaddr:  uint64(r.sym.Value + int64(r.rel.Off)),
+                       Lrtype:  r.rtype,
+                       Lsymndx: r.symndx,
+               }
+
+               if r.sym.Sect != nil {
+                       ldr.Lrsecnm = f.getXCOFFscnum(r.sym.Sect)
+               }
+
+               reloctab = append(reloctab, ldr)
+       }
 
        off += uint64(16 * len(dynimpreloc))
        reloctab = append(reloctab, dynimpreloc...)
@@ -1083,8 +1098,7 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
                ctxt.Out.Write8(0) // null terminator
        }
 
-       loaderOff = globalOff
-       loaderSize = off + uint64(stlen)
+       f.loaderSize = off + uint64(stlen)
        ctxt.Out.Flush()
 
        /* again for printing */
@@ -1148,8 +1162,12 @@ func (f *xcoffFile) writeFileHeader(ctxt *Link) {
                f.xahdr.Ovstamp = 1 // based on dump -o
                f.xahdr.Omagic = 0x10b
                copy(f.xahdr.Omodtype[:], "1L")
-               f.xahdr.Oentry = uint64(Entryvalue(ctxt))
-               f.xahdr.Otoc = uint64(ctxt.Syms.ROLookup("TOC", 0).Value)
+               entry := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
+               f.xahdr.Oentry = uint64(entry.Value)
+               f.xahdr.Osnentry = f.getXCOFFscnum(entry.Sect)
+               toc := ctxt.Syms.ROLookup("TOC", 0)
+               f.xahdr.Otoc = uint64(toc.Value)
+               f.xahdr.Osntoc = f.getXCOFFscnum(toc.Sect)
 
                // Based on dump -o
                f.xahdr.Oalgntext = 0x5
@@ -1175,90 +1193,47 @@ func xcoffwrite(ctxt *Link) {
 }
 
 // Generate XCOFF assembly file
-func Asmbxcoff(ctxt *Link) {
-       // initial offset for sections
-       if ctxt.BuildMode == BuildModeExe {
-               // search entry section number
-               eaddr := uint64(Entryvalue(ctxt))
-               for _, sect := range append(Segtext.Sections, Segdata.Sections...) {
-                       if eaddr-sect.Vaddr <= sect.Length {
-                               xfile.xahdr.Osnentry = int16(sect.Extnum)
-                       }
-               }
-
-               // check
-               if xfile.xahdr.Osnentry == 0 {
-                       Exitf("internal error: Section number for entry point (addr = 0x%x) not found", eaddr)
-               }
-
-       }
-
-       // add text sections
-       for _, sect := range Segtext.Sections {
-               // ctxt.Logf(".text: %s \n", sect.Name)
-               s := xfile.addSection(sect)
-               s.Sflags = STYP_TEXT
-
-               // use sect.Name because of convertion inside scnhdr
-               if sect.Name == ".text" {
-                       xfile.xahdr.Otextstart = s.Spaddr
-                       xfile.xahdr.Otsize = s.Ssize
-                       xfile.xahdr.Osntext = sect.Extnum
-               }
-       }
-
-       // add data sections
-       var (
-               snoptrdata,
-               sdata,
-               sbss,
-               snoptrbss *sym.Section
-       )
-       for _, sect := range Segdata.Sections {
-               if sect.Name == ".noptrdata" {
-                       snoptrdata = sect
-               }
-               if sect.Name == ".noptrbss" {
-                       snoptrbss = sect
-               }
-               if sect.Name == ".data" {
-                       sdata = sect
-               }
-               if sect.Name == ".bss" {
-                       sbss = sect
-               }
-       }
-
-       // On AIX, there must be only one data and one bss section.
-       // Therefore, their noptr section is merged within them.
-       // The length of the new section must be recomputed to handle defautl gap
-       // between GO sections as AIX doesn't allow it.
-
-       // Merge .noptrdata inside .data
-       sdata.Vaddr = snoptrdata.Vaddr
-       sdata.Length = sbss.Vaddr - sdata.Vaddr
-       s := xfile.addSection(sdata)
-       s.Sflags = STYP_DATA
-       xfile.xahdr.Odatastart = s.Spaddr
+func Asmbxcoff(ctxt *Link, fileoff int64) {
+       xfile.sectNameToScnum = make(map[string]int16)
+
+       // Add sections
+       s := xfile.addSection(".text", Segtext.Vaddr, Segtext.Length, Segtext.Fileoff, STYP_TEXT)
+       xfile.xahdr.Otextstart = s.Svaddr
+       xfile.xahdr.Osntext = xfile.sectNameToScnum[".text"]
+       xfile.xahdr.Otsize = s.Ssize
+
+       s = xfile.addSection(".data", Segdata.Vaddr, Segdata.Filelen, Segdata.Fileoff, STYP_DATA)
+       xfile.xahdr.Odatastart = s.Svaddr
+       xfile.xahdr.Osndata = xfile.sectNameToScnum[".data"]
        xfile.xahdr.Odsize = s.Ssize
-       xfile.xahdr.Osndata = sdata.Extnum
 
-       // Merge .noptrbss inside .bss
-       sbss.Length = snoptrbss.Vaddr + snoptrbss.Length - sbss.Vaddr
-       s = xfile.addSection(sbss)
-       s.Sflags = STYP_BSS
+       s = xfile.addSection(".bss", Segdata.Vaddr+Segdata.Filelen, Segdata.Length-Segdata.Filelen, 0, STYP_BSS)
+       xfile.xahdr.Osnbss = xfile.sectNameToScnum[".bss"]
        xfile.xahdr.Obsize = s.Ssize
-       xfile.xahdr.Osnbss = sbss.Extnum
-       s.Sscnptr = 0
 
-       // add dwarf section
+       // add dwarf sections
        for _, sect := range Segdwarf.Sections {
                xfile.addDwarfSection(sect)
        }
 
-       // Loader section must be add at the end because of sect.Extnum
-       // in others sections
-       xfile.addLoaderSection(loaderSize, loaderOff)
+       // add and write remaining sections
+       if ctxt.LinkMode == LinkInternal {
+               // Loader section
+               if ctxt.BuildMode == BuildModeExe {
+                       Loaderblk(ctxt, uint64(fileoff))
+                       s = xfile.addSection(".loader", 0, xfile.loaderSize, uint64(fileoff), STYP_LOADER)
+                       xfile.xahdr.Osnloader = xfile.sectNameToScnum[".loader"]
+               }
+       } else {
+               // TODO: Relocation
+       }
+
+       // Write symbol table
+       symo := Rnd(ctxt.Out.Offset(), int64(*FlagRound))
+       xfile.symtabOffset = symo
+       ctxt.Out.SeekSet(int64(symo))
+       xfile.asmaixsym(ctxt)
 
+       // write headers
        xcoffwrite(ctxt)
 }
index 2ec5a2b18b10f0dbd01aa8b7348d8508fce2282b..a5784bc640556aedec18d49618d5d08c9ea13193 100644 (file)
@@ -953,13 +953,6 @@ func asmb(ctxt *ld.Link) {
        ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
        ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
 
-       loadersize := uint64(0)
-       if ctxt.HeadType == objabi.Haix && ctxt.BuildMode == ld.BuildModeExe {
-               loadero := uint64(ld.Rnd(int64(ld.Segdwarf.Fileoff+ld.Segdwarf.Filelen), int64(*ld.FlagRound)))
-               ctxt.Out.SeekSet(int64(loadero))
-               loadersize = ld.Loaderblk(ctxt, loadero)
-       }
-
        /* output symbol table */
        ld.Symsize = 0
 
@@ -981,14 +974,7 @@ func asmb(ctxt *ld.Link) {
                        symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
 
                case objabi.Haix:
-                       symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-
-                       // Add loader size if needed
-                       if ctxt.BuildMode == ld.BuildModeExe {
-                               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-                               symo += uint32(loadersize)
-                       }
-                       symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
+                       // Nothing to do
                }
 
                ctxt.Out.SeekSet(int64(symo))
@@ -1019,7 +1005,7 @@ func asmb(ctxt *ld.Link) {
                        }
 
                case objabi.Haix:
-                       ld.Asmaixsym(ctxt)
+                       // symtab must be added once sections have been created in ld.Asmbxcoff
                        ctxt.Out.Flush()
                }
        }
@@ -1048,7 +1034,9 @@ func asmb(ctxt *ld.Link) {
                ld.Asmbelf(ctxt, int64(symo))
 
        case objabi.Haix:
-               ld.Asmbxcoff(ctxt)
+               fileoff := uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
+               fileoff = uint32(ld.Rnd(int64(fileoff), int64(*ld.FlagRound)))
+               ld.Asmbxcoff(ctxt, int64(fileoff))
        }
 
        ctxt.Out.Flush()