2014-10-11 8 views
7

Sto utilizzando alcuni strumenti LLVM (come) come librerie statiche. Cioè Ho copiato source llvm-nm.cpp, rinominato main(..) in llvm_nm(..) e lo ho compilato come libreria statica. Vorrei inoltrare l'output standard al mio file.Come reindirizzare llvm :: outs() in un file?

Ho cercato di utilizzare l'approccio seguente:

int out_fd, err_fd; 
    fpos_t out_pos, err_pos; 

    // redirect out 
    fflush(stdout); 
    fgetpos(stdout, &out_pos); 
    out_fd = dup(fileno(stdout)); 
    freopen(outFilename, "w", stdout); 

    // execute 
    int ret = llvm_nm(argc_, argv_); 

    // restore output 
    fflush(stdout); 
    dup2(out_fd, fileno(stdout)); 
    close(out_fd); 
    clearerr(stdout); 
    fsetpos(stdout, &out_pos); 

Il problema è che non è inoltrato (funziona se aggiungo printf() nel codice sorgente nm ma non per nm uscita). Ho looke alla fonte e posso vedere l'uscita viene fatto usando llvm::outs() flusso:

outs() << "Archive map" << "\n"; 

E it's implemented il modo successivo:

/// outs() - This returns a reference to a raw_ostream for standard output. 
00702 /// Use it like: outs() << "foo" << "bar"; 
00703 raw_ostream &llvm::outs() { 
00704 // Set buffer settings to model stdout behavior. 
00705 // Delete the file descriptor when the program exits, forcing error 
00706 // detection. If you don't want this behavior, don't use outs(). 
00707 static raw_fd_ostream S(STDOUT_FILENO, true); 
00708 return S; 
00709 } 

come posso reindirizzare l'output a mio file?

risposta

2

Non sembra essere un modo semplice per farlo: non esiste un costruttore copia/assegnazione in llvm::raw_fd_ostream né in llvm::raw_ostream. E il trucco freopen non funziona neanche perché il descritor di file intero viene utilizzato per inizializzare l'oggetto restituito da llvm::outs().

L'unico modo che vedo è utilizzare LD_PRELOAD per modificare l'implementazione di llvm::outs() al volo, o trucchi di linker simili, ma mi sembra molto intrusivo. Forse contrassegna il simbolo originale come debole e poi lo sostituisce nel tuo grimorio?

5

Mi rendo conto che questa è una vecchia domanda, tuttavia, mi sono imbattuto nel cercare alcune semplici informazioni per il flusso di llvm() che ho trovato here.

Uno degli esempi che viene fornito con LLVM "Brainf" usa in questo modo:

... 

    raw_ostream *out = &outs(); 
    if (!JIT) { 
    if (OutputFilename == "") { 
     std::string base = InputFilename; 
     if (InputFilename == "-") { base = "a"; } 

     // Use default filename. 
     OutputFilename = base+".bc"; 
    } 
    if (OutputFilename != "-") { 
     std::error_code EC; 
     out = new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None); 
    } 
    } 

    ... 

    if (out != &outs()) 
    delete out; 

    ... 

così sembra suggerire che siete al sicuro per reindirizzare.

Nota: in questo esempio OutputFileName/inputfilename sono tipi std :: string creati con libreria di supporto di LLVM CommandLine.

Problemi correlati