github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/link/internal/riscv64/asm.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package riscv64
     6  
     7  import (
     8  	"github.com/gagliardetto/golang-go/cmd/internal/obj/riscv"
     9  	"github.com/gagliardetto/golang-go/cmd/internal/objabi"
    10  	"github.com/gagliardetto/golang-go/cmd/internal/sys"
    11  	"github.com/gagliardetto/golang-go/cmd/link/internal/ld"
    12  	"github.com/gagliardetto/golang-go/cmd/link/internal/sym"
    13  	"fmt"
    14  	"log"
    15  )
    16  
    17  func gentext(ctxt *ld.Link) {
    18  }
    19  
    20  func adddynrela(ctxt *ld.Link, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) {
    21  	log.Fatalf("adddynrela not implemented")
    22  }
    23  
    24  func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
    25  	log.Fatalf("adddynrel not implemented")
    26  	return false
    27  }
    28  
    29  func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
    30  	log.Fatalf("elfreloc1")
    31  	return false
    32  }
    33  
    34  func elfsetupplt(ctxt *ld.Link) {
    35  	log.Fatalf("elfsetuplt")
    36  }
    37  
    38  func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
    39  	log.Fatalf("machoreloc1 not implemented")
    40  	return false
    41  }
    42  
    43  func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
    44  	switch r.Type {
    45  	case objabi.R_CALLRISCV:
    46  		// Nothing to do.
    47  		return val, true
    48  
    49  	case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE:
    50  		pc := s.Value + int64(r.Off)
    51  		off := ld.Symaddr(r.Sym) + r.Add - pc
    52  
    53  		// Generate AUIPC and second instruction immediates.
    54  		low, high, err := riscv.Split32BitImmediate(off)
    55  		if err != nil {
    56  			ld.Errorf(s, "R_RISCV_PCREL_ relocation does not fit in 32-bits: %d", off)
    57  		}
    58  
    59  		auipcImm, err := riscv.EncodeUImmediate(high)
    60  		if err != nil {
    61  			ld.Errorf(s, "cannot encode R_RISCV_PCREL_ AUIPC relocation offset for %s: %v", r.Sym.Name, err)
    62  		}
    63  
    64  		var secondImm, secondImmMask int64
    65  		switch r.Type {
    66  		case objabi.R_RISCV_PCREL_ITYPE:
    67  			secondImmMask = riscv.ITypeImmMask
    68  			secondImm, err = riscv.EncodeIImmediate(low)
    69  			if err != nil {
    70  				ld.Errorf(s, "cannot encode R_RISCV_PCREL_ITYPE I-type instruction relocation offset for %s: %v", r.Sym.Name, err)
    71  			}
    72  		case objabi.R_RISCV_PCREL_STYPE:
    73  			secondImmMask = riscv.STypeImmMask
    74  			secondImm, err = riscv.EncodeSImmediate(low)
    75  			if err != nil {
    76  				ld.Errorf(s, "cannot encode R_RISCV_PCREL_STYPE S-type instruction relocation offset for %s: %v", r.Sym.Name, err)
    77  			}
    78  		default:
    79  			panic(fmt.Sprintf("Unknown relocation type: %v", r.Type))
    80  		}
    81  
    82  		auipc := int64(uint32(val))
    83  		second := int64(uint32(val >> 32))
    84  
    85  		auipc = (auipc &^ riscv.UTypeImmMask) | int64(uint32(auipcImm))
    86  		second = (second &^ secondImmMask) | int64(uint32(secondImm))
    87  
    88  		return second<<32 | auipc, true
    89  	}
    90  
    91  	return val, false
    92  }
    93  
    94  func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
    95  	log.Fatalf("archrelocvariant")
    96  	return -1
    97  }
    98  
    99  func asmb(ctxt *ld.Link) {
   100  	if ctxt.IsELF {
   101  		ld.Asmbelfsetup()
   102  	}
   103  
   104  	sect := ld.Segtext.Sections[0]
   105  	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
   106  	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
   107  	for _, sect = range ld.Segtext.Sections[1:] {
   108  		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
   109  		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
   110  	}
   111  
   112  	if ld.Segrodata.Filelen > 0 {
   113  		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
   114  		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
   115  	}
   116  	if ld.Segrelrodata.Filelen > 0 {
   117  		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
   118  		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
   119  	}
   120  
   121  	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
   122  	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
   123  
   124  	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
   125  	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
   126  }
   127  
   128  func asmb2(ctxt *ld.Link) {
   129  	ld.Symsize = 0
   130  	ld.Lcsize = 0
   131  	symo := uint32(0)
   132  
   133  	if !*ld.FlagS {
   134  		if !ctxt.IsELF {
   135  			ld.Errorf(nil, "unsupported executable format")
   136  		}
   137  
   138  		symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
   139  		symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
   140  		ctxt.Out.SeekSet(int64(symo))
   141  
   142  		ld.Asmelfsym(ctxt)
   143  		ctxt.Out.Flush()
   144  		ctxt.Out.Write(ld.Elfstrdat)
   145  
   146  		if ctxt.LinkMode == ld.LinkExternal {
   147  			ld.Elfemitreloc(ctxt)
   148  		}
   149  	}
   150  
   151  	ctxt.Out.SeekSet(0)
   152  	switch ctxt.HeadType {
   153  	case objabi.Hlinux:
   154  		ld.Asmbelf(ctxt, int64(symo))
   155  	default:
   156  		ld.Errorf(nil, "unsupported operating system")
   157  	}
   158  	ctxt.Out.Flush()
   159  
   160  	if *ld.FlagC {
   161  		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
   162  		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
   163  		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
   164  		fmt.Printf("symsize=%d\n", ld.Symsize)
   165  		fmt.Printf("lcsize=%d\n", ld.Lcsize)
   166  		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
   167  	}
   168  }