PC-Relative Branching in ARM GAS?

Sorry for the noobish question, but I'm thoroughly confused.

I've been trying to break into ARM ASM using GAS, however, none of my programs have actually assembled properly due to a branching problem, where the assembler has decided to use absolute addressing rather than PC-relative addressing.

I'm programming for the GBA and am using devkitadv. I use a combination of two programs in the program suite named "arm-agb-elf-as" and "arm-agb-elf-objcopy". The "as" creates a *.elf file, which "objcopy" translates into a raw binary file. I also disassemble the *.elf file with another program called "arm-agb-elf-objdump", and can confirm from that that the branch statements are not PC-relative. I've also looked at the raw binary files and the opcodes match the disassembly.

What I want to know is either:

a) What option(s) do I need for "as" and/or "objcopy" to successfully create PC-relative branching in my binary files?

or

b) Is there an easier way, perhaps with a different program?

Thanks in advance.
«1

Comments

  • : Sorry for the noobish question, but I'm thoroughly confused.
    :
    : I've been trying to break into ARM ASM using GAS, however, none of
    : my programs have actually assembled properly due to a branching
    : problem, where the assembler has decided to use absolute addressing
    : rather than PC-relative addressing.
    :
    : I'm programming for the GBA and am using devkitadv. I use a
    : combination of two programs in the program suite named
    : "arm-agb-elf-as" and "arm-agb-elf-objcopy". The "as" creates a *.elf
    : file, which "objcopy" translates into a raw binary file. I also
    : disassemble the *.elf file with another program called
    : "arm-agb-elf-objdump", and can confirm from that that the branch
    : statements are not PC-relative. I've also looked at the raw binary
    : files and the opcodes match the disassembly.
    :
    : What I want to know is either:
    :
    : a) What option(s) do I need for "as" and/or "objcopy" to
    : successfully create PC-relative branching in my binary files?
    :
    : or
    :
    : b) Is there an easier way, perhaps with a different program?
    :
    : Thanks in advance.
    :

    Look at what gcc uses.

    I think there's some kind of pretend option...
  • : : Sorry for the noobish question, but I'm thoroughly confused.
    : :
    : : I've been trying to break into ARM ASM using GAS, however, none of
    : : my programs have actually assembled properly due to a branching
    : : problem, where the assembler has decided to use absolute addressing
    : : rather than PC-relative addressing.
    : :
    : : I'm programming for the GBA and am using devkitadv. I use a
    : : combination of two programs in the program suite named
    : : "arm-agb-elf-as" and "arm-agb-elf-objcopy". The "as" creates a *.elf
    : : file, which "objcopy" translates into a raw binary file. I also
    : : disassemble the *.elf file with another program called
    : : "arm-agb-elf-objdump", and can confirm from that that the branch
    : : statements are not PC-relative. I've also looked at the raw binary
    : : files and the opcodes match the disassembly.
    : :
    : : What I want to know is either:
    : :
    : : a) What option(s) do I need for "as" and/or "objcopy" to
    : : successfully create PC-relative branching in my binary files?
    : :
    : : or
    : :
    : : b) Is there an easier way, perhaps with a different program?
    : :
    : : Thanks in advance.
    : :
    :
    : Look at what gcc uses.
    :
    : I think there's some kind of pretend option...

    I've looked at the options for gcc, gas, and objcopy. I can't find any such option.
  • : Sorry for the noobish question, but I'm thoroughly confused.
    :
    : I've been trying to break into ARM ASM using GAS, however, none of
    : my programs have actually assembled properly due to a branching
    : problem, where the assembler has decided to use absolute addressing
    : rather than PC-relative addressing.
    :
    : I'm programming for the GBA and am using devkitadv. I use a
    : combination of two programs in the program suite named
    : "arm-agb-elf-as" and "arm-agb-elf-objcopy". The "as" creates a *.elf
    : file, which "objcopy" translates into a raw binary file. I also
    : disassemble the *.elf file with another program called
    : "arm-agb-elf-objdump", and can confirm from that that the branch
    : statements are not PC-relative. I've also looked at the raw binary
    : files and the opcodes match the disassembly.
    :
    : What I want to know is either:
    :
    : a) What option(s) do I need for "as" and/or "objcopy" to
    : successfully create PC-relative branching in my binary files?
    :
    : or
    :
    : b) Is there an easier way, perhaps with a different program?
    :
    : Thanks in advance.
    :

    I've found an alternative: FASMARM. It outputs a raw binary file and is simple to use. However, the syntax is different enough so that the code from GAS will be incompatible, so any help on the original problem would be greatly appreciated.
  • : :
    : : Look at what gcc uses.
    : :
    : : I think there's some kind of pretend option...
    :
    : I've looked at the options for gcc, gas, and objcopy. I can't find
    : any such option.
    :

    Then work around the problem...

    Make your own program that replace the assembler, and make it print out the parameters.
  • : : :
    : : : Look at what gcc uses.
    : : :
    : : : I think there's some kind of pretend option...
    : :
    : : I've looked at the options for gcc, gas, and objcopy. I can't find
    : : any such option.
    : :
    :
    : Then work around the problem...
    :
    : Make your own program that replace the assembler, and make it print
    : out the parameters.

    That's basically what I arrived at. I've already substantially started my own assembler, but it's a long, slow, inefficient solution. GAS would certainly be suitable if only I could figure out how to configure it. Binutils are all very configurable in so many ways, so there must be a way to generate PC-relative branches.

    Oh well, thanks for the help anyway. I've already got my workaround (FASMARM produces PC-relative code at the expense of compatibility with GAS mnemonics), as I mentioned in another post. Still, if anyone else knows how to configure GAS properly, it would be a helpful learning experience.
  • : : : :
    : : : : Look at what gcc uses.
    : : : :
    : : : : I think there's some kind of pretend option...
    : : :
    : : : I've looked at the options for gcc, gas, and objcopy. I can't find
    : : : any such option.
    : : :
    : :
    : : Then work around the problem...
    : :
    : : Make your own program that replace the assembler, and make it print
    : : out the parameters.
    :
    : That's basically what I arrived at. I've already substantially
    : started my own assembler, but it's a long, slow, inefficient
    : solution. GAS would certainly be suitable if only I could figure out
    : how to configure it. Binutils are all very configurable in so many
    : ways, so there must be a way to generate PC-relative branches.
    :
    : Oh well, thanks for the help anyway. I've already got my workaround
    : (FASMARM produces PC-relative code at the expense of compatibility
    : with GAS mnemonics), as I mentioned in another post. Still, if
    : anyone else knows how to configure GAS properly, it would be a
    : helpful learning experience.
    :

    As I said, replace GAS with a dummy program that outputs it's parameters to a log file, and you're set.

    Sorry for my bad explaining...

    Something like this:
    [code]
    FILE* file
    main(int argc, char** argv){
    file=fopen();
    for(int i=0;i<argc;++i)
    fprintf(file,"%s
    ",argv[i]);
    }
    [/code]
  • Sorry, I'm still a noob in many areas. I don't quite understand. I understand the "dummy program" and "log file", but I don't understand what "parameters" you're talking about, and how it helps solve the problem.

    You'll also have to forgive me if my knowledge of C is a little flimsy. I'm guessing that a FILE* type is a handle on a file, and that fopen() prepares a file for writing, but what file and how to use the file, I have no idea. If you can give me the concept in more general, less platform/language specific terms, that would be great. Thanks in advance.
  • : Sorry, I'm still a noob in many areas. I don't quite understand. I
    : understand the "dummy program" and "log file", but I don't
    : understand what "parameters" you're talking about, and how it helps
    : solve the problem.
    :
    : You'll also have to forgive me if my knowledge of C is a little
    : flimsy. I'm guessing that a FILE* type is a handle on a file, and
    : that fopen() prepares a file for writing, but what file and how to
    : use the file, I have no idea. If you can give me the concept in more
    : general, less platform/language specific terms, that would be great.
    : Thanks in advance.
    :

    The little program I wrote does nothing but takes the paramters passed to it and print it to a file.
    If you'd have tried to compile my program it would have given an error, becouse I didn't supply the parameters to fopen.

    Check you man page: man fopen
    The line should've looked something like this:
    file=fopen("log.log","a");


    When gcc executes the assembler, it does so with some parameters, and if you know those parameters you can assemble like the compiler, and thus produce the same output, which is the sollution to your first problem, if I understood it right.
  • I think I get it now! You replace the assembler program with the program you supplied (with the modification), run the assembly instructions through gcc, and read the options passed to the assembler from the file. Thank you, thank you, thank you. I'll try it now.
  • : I think I get it now! You replace the assembler program with the
    : program you supplied (with the modification), run the assembly
    : instructions through gcc, and read the options passed to the
    : assembler from the file. Thank you, thank you, thank you. I'll try
    : it now.
    :

    I've tried it. I didn't get anything I hadn't already tried. It logged the program name (of course), the architecture (-maram7tdmi), an output file and an input file (both random temporary files). I also tried the -k option (which is supposed to generate PIC), but it didn't work either.
  • : : I think I get it now! You replace the assembler program with the
    : : program you supplied (with the modification), run the assembly
    : : instructions through gcc, and read the options passed to the
    : : assembler from the file. Thank you, thank you, thank you. I'll try
    : : it now.
    : :
    :
    : I've tried it. I didn't get anything I hadn't already tried. It
    : logged the program name (of course), the architecture (-maram7tdmi),
    : an output file and an input file (both random temporary files). I
    : also tried the -k option (which is supposed to generate PIC), but it
    : didn't work either.
    :

    Hmm, try copying the input file to a different location and see what's in it.

    And maybe look at the linker...

    I don't know more than that...
  • : : : I think I get it now! You replace the assembler program with the
    : : : program you supplied (with the modification), run the assembly
    : : : instructions through gcc, and read the options passed to the
    : : : assembler from the file. Thank you, thank you, thank you. I'll try
    : : : it now.
    : : :
    : :
    : : I've tried it. I didn't get anything I hadn't already tried. It
    : : logged the program name (of course), the architecture (-maram7tdmi),
    : : an output file and an input file (both random temporary files). I
    : : also tried the -k option (which is supposed to generate PIC), but it
    : : didn't work either.
    : :
    :
    : Hmm, try copying the input file to a different location and see
    : what's in it.
    :
    : And maybe look at the linker...
    :
    : I don't know more than that...

    I thought of the input file, but gcc obviously deletes the temporary files after use. As for the linker, is it necessary? The executable doesn't need to be linked with anything.
  • : : : : I think I get it now! You replace the assembler program with the
    : : : : program you supplied (with the modification), run the assembly
    : : : : instructions through gcc, and read the options passed to the
    : : : : assembler from the file. Thank you, thank you, thank you. I'll try
    : : : : it now.
    : : : :
    : : :
    : : : I've tried it. I didn't get anything I hadn't already tried. It
    : : : logged the program name (of course), the architecture (-maram7tdmi),
    : : : an output file and an input file (both random temporary files). I
    : : : also tried the -k option (which is supposed to generate PIC), but it
    : : : didn't work either.
    : : :
    : :
    : : Hmm, try copying the input file to a different location and see
    : : what's in it.
    : :
    : : And maybe look at the linker...
    : :
    : : I don't know more than that...
    :
    : I thought of the input file, but gcc obviously deletes the temporary
    : files after use. As for the linker, is it necessary? The executable
    : doesn't need to be linked with anything.
    :

    Aren't they linked after they're assembled?

    And gcc deleting the files can be helped.
    Just add a line in the asm replacement program that copies the file.
    Or simpler is to make the asm prog pause and print the filename to stdout, and then copy it manually.
  • : Aren't they linked after they're assembled?
    :
    : And gcc deleting the files can be helped.
    : Just add a line in the asm replacement program that copies the file.
    : Or simpler is to make the asm prog pause and print the filename to
    : stdout, and then copy it manually.

    They don't need to be linked. There are no libraries, and I add the data in manually with .word/.byte directives.

    I've also looked at some disassembled .elf files generated by gcc, and I've noticed that gcc only uses BX instructions instead of the usual B/BL instructions. BX instructions branch to an absolute location as stored in a register, whereas B/BL branch relatively to the PC. BX is considerably less efficient, but obviously easier for gcc's framework.

    Basically, the point is that I doubt that this approach will work. Gcc doesn't need to be configured properly with its approach. Thanks (again) for trying.
  • : They don't need to be linked. There are no libraries, and I add the
    : data in manually with .word/.byte directives.
    :
    : I've also looked at some disassembled .elf files generated by gcc,
    : and I've noticed that gcc only uses BX instructions instead of the
    : usual B/BL instructions. BX instructions branch to an absolute
    : location as stored in a register, whereas B/BL branch relatively to
    : the PC. BX is considerably less efficient, but obviously easier for
    : gcc's framework.
    :
    : Basically, the point is that I doubt that this approach will work.
    : Gcc doesn't need to be configured properly with its approach. Thanks
    : (again) for trying.
    :

    I think it's called short jmping too, the oposit of long jmping.
    Try to search for it and maybe you'll find some more info...
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

In this Discussion